package com.gitee.ayezs;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gitee.ayezs.annotation.Default;
import com.gitee.ayezs.annotation.wrapper.Eq;
import com.gitee.ayezs.annotation.wrapper.WrapperAnnotation;
import com.gitee.ayezs.marshaller.CommonWrapperBuild;
import com.gitee.ayezs.util.FindAnnotationInfo;
import com.gitee.ayezs.marshaller.WrapperBuilder;
import com.gitee.ayezs.util.AnnotationUtil;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 基于注解的QueryWrapper
 *
 * @author 庞冬皓
 */
public class AnnotationQueryWrapper<T> extends QueryWrapper<T> {
    //    public static List<Annotation> annotations = new ArrayList<>();

    public static Map<WrapperAnnotation, WrapperBuilder> marshallerMap = new HashMap<>();

    public AnnotationQueryWrapper(T entity) {
        this(entity, Default.class, "eq", new CommonWrapperBuild());

    }

    public AnnotationQueryWrapper(T entity, Class clazz) {
        this(entity, clazz, "eq", new CommonWrapperBuild());
    }

    public AnnotationQueryWrapper(T entity, Class clazz, String defaultMethod, WrapperBuilder defaultWrapperBuilder) {

        Field[] declaredFields = entity.getClass().getDeclaredFields();
        for (Field field :
                declaredFields) {
            List<FindAnnotationInfo> wrapperAnnotation1 = AnnotationUtil.findWrapperAnnotation(field);
            for (FindAnnotationInfo findAnnotationInfo : wrapperAnnotation1) {
                if (findAnnotationInfo != null && contains(findAnnotationInfo.getGroup(), clazz)) {
                    WrapperAnnotation wrapperAnnotation = findAnnotationInfo.getWrapperAnnotation();
                    if (wrapperAnnotation != null) {
                        WrapperBuilder wrapperBuilder1 = marshallerMap.get(wrapperAnnotation);
                        if (wrapperBuilder1 != null) {
                            wrapperBuilder1.build(this, field, entity, findAnnotationInfo.getCondition(), wrapperAnnotation.methodName());
                        } else {
                            WrapperBuilder wrapperBuilder;
                            try {
                                wrapperBuilder = wrapperAnnotation.marshaller().newInstance();
                                marshallerMap.put(wrapperAnnotation, wrapperBuilder);
                                wrapperBuilder.build(this, field, entity, findAnnotationInfo.getCondition(), wrapperAnnotation.methodName());
                            } catch (InstantiationException | IllegalAccessException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
            if (wrapperAnnotation1 == null || wrapperAnnotation1.size() == 0) {
                if(defaultMethod!=null && defaultWrapperBuilder!=null){
                    defaultWrapperBuilder.build(this, field, entity, null, defaultMethod);
                }
            }
        }
    }

    /**
     * 检索组中是否包含指定类或它的子类
     *
     * @param group
     * @param c
     * @return
     */
    private static boolean contains(Class[] group, Class c) {
        for (Class aClass : group) {
            if (c.isAssignableFrom(aClass)) {
                return true;
            }
        }
        return false;
    }
}
